﻿using System;
using System.Collections.Generic;
using Grimgine.Math;

namespace Grimgine.Scene
{
    /// <summary>
    /// 
    /// </summary>
    public class OctreeNode
    {
        private const int maxObjectsInNode = 5;
        private const float minSize = 5.0f;

        private Vector3 center;
        private float size;
        List<DrawableModel> modelList;

        OctreeNode nodeUFL;
        OctreeNode nodeUFR;
        OctreeNode nodeUBL;
        OctreeNode nodeUBR;
        OctreeNode nodeDFL;
        OctreeNode nodeDFR;
        OctreeNode nodeDBL;
        OctreeNode nodeDBR;
        List<OctreeNode> childList;

        public static int modelsDrawn;
        private static int modelsStoredInOctree;

        /// <summary>
        /// 
        /// </summary>
        public int ModelsDrawn
        {
            get { return modelsDrawn; }
            set { modelsDrawn = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="center"></param>
        /// <param name="size"></param>
        public OctreeNode(Vector3 center, float size)
        {
            this.center = center;
            this.size = size;
            modelList = new List<DrawableModel>();
            childList = new List<OctreeNode>(8);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public int Add()
        {
            return 0;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="modelID"></param>
        /// <param name="newWorldMatrix"></param>
        public void UpdateModelWorldMatrix(int modelID, Matrix4 newWorldMatrix)
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="modelID"></param>
        /// <returns></returns>
        private DrawableModel RemoveDrawableModel(int modelID)
        {
            DrawableModel dModel = null;
            return dModel;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dModel"></param>
        private void AddDrawableMode(DrawableModel dModel)
        {

        }

        /// <summary>
        /// 
        /// </summary>
        private void CreateChildNodes()
        {
            float sizeOver2 = size / 2.0f;
            float sizeOver4 = size / 4.0f;

            nodeUFR = new OctreeNode(center + new Vector3(sizeOver4, sizeOver4, -sizeOver4), sizeOver2);
            nodeUFL = new OctreeNode(center + new Vector3(-sizeOver4, sizeOver4, -sizeOver4), sizeOver2);
            nodeUBR = new OctreeNode(center + new Vector3(sizeOver4, sizeOver4, sizeOver4), sizeOver2);
            nodeUBL = new OctreeNode(center + new Vector3(-sizeOver4, sizeOver4, sizeOver4), sizeOver2);

            nodeDFR = new OctreeNode(center + new Vector3(sizeOver4, -sizeOver4, -sizeOver4), sizeOver2);
            nodeDFL = new OctreeNode(center + new Vector3(-sizeOver4, -sizeOver4, -sizeOver4), sizeOver2);
            nodeDBR = new OctreeNode(center + new Vector3(sizeOver4, -sizeOver4, sizeOver4), sizeOver2);
            nodeDBL = new OctreeNode(center + new Vector3(-sizeOver4, -sizeOver4, sizeOver4), sizeOver2);

            childList.Add(nodeUFR);
            childList.Add(nodeUFL);
            childList.Add(nodeUBR);
            childList.Add(nodeUBL);
            childList.Add(nodeDFR);
            childList.Add(nodeDFL);
            childList.Add(nodeDBR);
            childList.Add(nodeDBL);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dModel"></param>
        private void Distribute(DrawableModel dModel)
        {

        }

        /// <summary>
        /// 
        /// </summary>
        public void Draw()
        {

        }
    }
}
